<template>
  <div class="h100">
    <Row>
      <i-col class="h100" span="4">
        <div class="table-left">
          <Menu
            ref="formsMenu"
            class="menu-list"
            :active-name="selectedFormId"
            @on-select="handleMenuClick"
          >
            <MenuItem v-for="(item,key) in formList" :key="key" :name="item.id">{{item.title}}</MenuItem>
          </Menu>
        </div>
      </i-col>
      <i-col span="20" class="h100">
        <div class="back-newcot clearfix">
          <div class="back-work-template clearfix">
            <div class="clearfix" style="height: 100%;">
              <Row>
                <i-col span="18" class="h100">
                  <div class="table-center">
                    <Form :label-width="labelWidth">
                      <draggable
                        class="drop-box1"
                        :options="options"
                        :value="cloneFieldList"
                        @input="handleListChange"
                        @end="handleEnd"
                        @start="handleStart"
                      >
                        <template v-for="(item,key) in cloneFieldList">
                          <Row :key="key">
                            <i-col
                              v-for="(i, k) in item"
                              :key="k+i.field_name"
                              :span="i.style.single?24:12"
                            >
                              <div @click="handleSecMenuClick(i)">
                                <render-item
                                  :field="i"
                                  :active.sync="i.id==selectedField.id"
                                  :fieldType="i.component_type"
                                />
                              </div>
                            </i-col>
                          </Row>
                        </template>
                      </draggable>
                    </Form>
                  </div>
                </i-col>
                <i-col class="h100" span="6">
                  <field-setting
                    v-if="!!selectedField.id"
                    ref="fieldSetting"
                    :field="selectedField"
                    @on-change-field="handleChangeField"
                  >
                    <Checkbox v-model="showHideFields" @on-change="onChangeHideFields">显示隐藏字段</Checkbox>
                  </field-setting>
                </i-col>
              </Row>
            </div>
          </div>
          <div class="back-work-botemp clearfix">
            <div class="btn">
              <Button size="large" :loading="loading" @click="handleSave" type="primary">
                <span v-if="!loading">保存</span>
                <span v-else>保存中...</span>
              </Button>
            </div>
          </div>
        </div>
      </i-col>
    </Row>
  </div>
</template>
<script>
import { getFormList, getFormFields, updateFormFields } from '@/api/form.js';
import draggable from 'vuedraggable';
import renderItem from './components/render-item';
import fieldSetting from './components/field-setting.vue';
import { deepCopy } from '@/libs/util';
import './index.less';

export default {
  name: 'formFieldsSetting',
  components: { renderItem, fieldSetting, draggable },
  data() {
    return {
      options: { group: 'drag_list' },
      formList: [],
      fieldList: [],
      labelWidth: 80,
      cloneFieldList: [],
      selectedFormId: 0,
      loading: false,
      selectedField: {}, // 当前选中字段
      showHideFields: false,
      componentField: {
        cascader: 'cascader',
        select: 'select',
        radio: 'radio',
        staring: 'rate',
        mobile: 'input',
        textarea: 'input',
        text: 'input',
        attachments: 'upload',
        email: 'input',
        process: 'slider',
        money: 'number',
        number: 'number',
        daterange: 'date',
        time: 'time',
        datetime: 'date',
        treeselect: 'treeselect'
      }
    };
  },
  created() {
    getFormList().then(res => {
      this.formList = res.data.data.list;
      this.$nextTick(() => {
        this.handleMenuClick(res.data.data.list[0].id);
      });
    });
    this.$on('on-change-field', field => {
      this.handleChangeField(field);
    });
  },
  methods: {
    handleListChange(value) {},
    handleStart(event) {
      this.selectedField = this.cloneFieldList[event.oldIndex][0];
    },
    handleEnd(event) {
      const { newIndex, oldIndex } = event;
      const targetRow = this.cloneFieldList[newIndex];
      const sourceRow = this.cloneFieldList[oldIndex];

      this.cloneFieldList[newIndex] = sourceRow;
      this.cloneFieldList[oldIndex] = targetRow;

      let order = 1;
      const orderList = {};
      this.cloneFieldList = this.cloneFieldList.map((row, index) => {
        return row.map(field => {
          field.order = order;
          orderList[field.id] = order;
          order += 1;
          return field;
        });
      });

      this.fieldList = this.fieldList
        .map(f => {
          f.order = orderList[f.id] || 0;
          return f;
        })
        .sort((a, b) => a.order - b.order);
    },
    onChangeHideFields() {
      this.cloneFieldList = this.makeFieldList(this.fieldList);
    },
    /**
     * 保存设置
     *
     * @param {Object} field 字段属性
     * @param {Function} callback 回调函数
     */
    handleSave() {
      this.loading = true;
      updateFormFields(
        this.selectedFormId,
        this.fieldList.map((f, index) => {
          const field = { ...f };
          field.order = index + 1;
          return field;
        })
      )
        .then(res => {
          this.loading = false;
          this.$Message.success('更新成功');
        })
        .catch(err => {
          this.$Message.success('更新失败' + err);
          this.loading = false;
        });
    },
    /**
     * 改变字段属性
     *
     * @param {Object} field 字段属性
     * @param {Function} callback 回调函数
     */
    handleChangeField(field, callback) {
      if (field.props) {
        this.selectedField.props = Object.assign(
          this.selectedField.props,
          field.props
        );
      } else if (field.validate) {
        let fieldValidate = this.selectedField.validate;
        if (!Array.isArray(fieldValidate)) {
          fieldValidate = [fieldValidate];
        }
        if (fieldValidate.length == 0) {
          fieldValidate = [field.validate];
        } else {
          this.addValidate(field.name, fieldValidate, field.validate);
        }
        this.selectedField.validate = fieldValidate;
      } else if (field.ext) {
        this.selectedField.ext = Object.assign(
          this.selectedField.ext || {},
          field.ext
        );
      } else {
        this.selectedField = Object.assign(this.selectedField, field);
      }

      this.fieldList = this.fieldList.map(f => {
        let field = { ...f };
        if (f.id === this.selectedField.id) {
          field = { ...this.selectedField };
        }
        return field;
      });
      this.cloneFieldList = this.makeFieldList(deepCopy(this.fieldList));
      callback && callback();
    },
    addValidate(requiredName, fieldValidate, validate) {
      const rIndex = fieldValidate.findIndex(f => Object.keys(f).includes(requiredName));
      if (rIndex != -1) {
        fieldValidate[rIndex] = validate;
      } else {
        fieldValidate.push(validate);
      }
    },
    handleMenuClick(id) {
      // 一级菜单点击事件
      this.selectedFormId = id;
      getFormFields(id).then(res => {
        const fieldList = res.data.data.sort((a, b) => a.order - b.order);
        this.fieldList = fieldList;

        this.cloneFieldList = this.makeFieldList(fieldList);
        this.selectedField = this.cloneFieldList[0][0];
      });
    },
    /**
     * 初始化字段列表为二维数组
     *
     * @param {Array} field 字段Array
     */
    makeFieldList(list) {
      const cloneFieldList = [];
      let rowFieldList = [];
      let showList = [];
      if (this.showHideFields) {
        showList = list;
      } else {
        showList = list.filter(f => f.display === 1);
      }
      showList.forEach(item => {
        if (!item.props) {
          item.props = {};
        }
        if (!item.style) {
          item.style = {};
        }
        // 获取组件类型
        item.component_type = this.componentField[item.field_type];

        if (rowFieldList.length === 0) {
          if (item.style.single) {
            cloneFieldList.push([item]);
          } else {
            rowFieldList.push(item);
          }
        } else {
          if (item.style.single) {
            cloneFieldList.push(rowFieldList);
            cloneFieldList.push([item]);
            rowFieldList = [];
          } else {
            rowFieldList.push(item);
            cloneFieldList.push(rowFieldList);
            rowFieldList = [];
          }
        }
      });
      if (rowFieldList.length !== 0) {
        cloneFieldList.push(rowFieldList);
      }
      return cloneFieldList;
    },
    handleSecMenuClick(field) {
      this.selectedField = this.fieldList.find(f => f.id === field.id);
    }
  }
};
</script>
<style lang="less" scoped>
</style>
<style lang="less" scoped>
.h100 {
  height: 100%;
  .ivu-row {
    height: 100%;
    .ivu-col {
      max-height: 100%;
      overflow: auto;
      .ivu-menu {
        width: auto;
        height: 100%;
      }
    }
  }
}
.menu-list {
  width: auto !important;
}
</style>
